$(document).ready(function() {
paper.install(window);window.onload = ready;

function ready() {

    init();

    function init() {
        paper.setup('canvas');
        start();
    }

    function start() {

        var projectId = $('#project_id_input').val();
        var version = null;
        var resolution = null;
        var canvasWidth = $('#canvas').width();
        var canvasHeight = $('#canvas').height();
        var canvasOriginRadius = 6;
        var originX = 0.0;
        var originY = 0.0;
        var mapWidth = 0;
        var mapHeight = 0;
        var mapCenterX = canvasWidth / 2;
        var mapCenterY = canvasHeight / 2;
        var mapOriginX = 0;
        var mapOriginY = 0;
        var mapScale = 1.0;
        var mapUrl = $('#map_input').val();
        var mapLoaded = false;
        var mapRaster = null;
        var prjUrl = $('#prj_input').val();
        var prjLoaded = false;

        var dataObj = null;
        var pathObj = null;

        var nodeRadius = 4;
        var nodeNum = 0;
        var nodeArr = [];
        var originNodeId = 0;
        var originNodeDrawing = false;
        const NODE_STATE_NORMAL = 0x0001;
        const NODE_STATE_FOCUSED = 0x0002;
        const NODE_STATE_SELECTED = 0x0004;
        const NODE_STATE_ORIGIN = 0x0003;

        var pathNum = 0;
        var pathArr = [];
        var pathCur = {};
        pathCur.fromPoint = null;
        pathCur.toPoint = null;
        var pathCurDraw = {};
        pathCurDraw.from = {};
        pathCurDraw.from.x = null;
        pathCurDraw.from.y = null;
        pathCurDraw.to = {};
        pathCurDraw.to.x = null;
        pathCurDraw.to.y = null;
        pathCurDraw.path = null;
        pathCurDraw.drawing = false;
        pathCurDraw.start = false;
        const PATH_STATE_NORMAL = 0x0001;
        const PATH_STATE_FOCUSED = 0x0002;
        const PATH_STATE_SELECTED = 0x0003;

        loadData();

        function loadData() {

            getMap();
            getPrj();

            var timerId = window.setInterval(function () {
                if(mapLoaded && prjLoaded) {
                    window.clearInterval(timerId);
                    render();
                }
            }, 10);
        }

        function getMap() {

            if(!mapUrl) {
                alert('map url empty !');
                return;
            }

            mapRaster = new Raster(mapUrl);
            mapRaster.position = view.center;
            mapRaster.on('load', function() {
                mapLoaded = true;
            });
        }

        function getPrj() {

            if(!prjUrl) {
                alert('prj url empty !');
                return;
            }

            $.get(prjUrl, function(result) {
                if(!result) return;
                console.log('getPrj()<<<--- result = ' + result);

                try {
                    dataObj = JSON.parse(result);
                } catch (e) {
                    alert('data解析失败！' + e.name + ": " + e.message);
                    return;
                }

                version = dataObj[0] / 10;
                resolution = dataObj[1] / 2;
                mapWidth = dataObj[4] / 2;
                mapHeight = dataObj[5] / 3;

                originX = Math.abs(dataObj[2] / 3 / resolution);
                originY = mapHeight - Math.abs(dataObj[3] / 4 / resolution);
                originNodeId = dataObj[6][0];
                pathObj = dataObj[6][1];

                nodeNum = pathObj.length;
                if(nodeNum < 0)  return;

                prjLoaded = true;
            });
        }

        function render() {

            convertNodePath();
            setNodeData();
            setMapOrigin();
            transNode();
            setMapScale();
            scaleMap();
            drawMap();
            // drawMapOrigin();
            scaleNode();
            drawNode();
            drawPath();
            listen();
            canvasAnimate();
        }

        function convertNodePath() {

            for(var i = 0; i < nodeNum; i++) {
                pathObj[i].id = i;
                pathObj[i][0] = pathObj[i][0] / 2 / resolution + originX;
                pathObj[i][1] = -(pathObj[i][1] / 3) / resolution + originY;
            }
        }

        function setNodeData() {

            for(var i = 0; i < nodeNum; i++) {
                var point = {};
                point.id = pathObj[i].id;
                var x = pathObj[i][0];
                var y = pathObj[i][1];
                point.x = x;
                point.y = y;
                nodeArr.push(point);
            }
        }

        function setMapOrigin() {

            mapOriginX = canvasWidth / 2 - mapWidth / 2;
            mapOriginY = canvasHeight / 2 - mapHeight / 2;
        }

        function transNode() {

            for(var i = 0; i < nodeNum; i++) {
                nodeArr[i].x = nodeArr[i].x + mapOriginX;
                nodeArr[i].y = nodeArr[i].y + mapOriginY;
            }
        }

        function setMapScale() {

            if(mapWidth >= mapHeight) {
                mapScale = canvasWidth / mapWidth;
            } else {
                mapScale = canvasHeight / mapHeight;
            }
        }

        function scaleMap() {

            mapWidth *= mapScale;
            mapHeight *= mapScale;
            setMapOrigin();
        }

        function scaleNode() {

            for(var i = 0; i < nodeNum; i++) {

                nodeArr[i].x = mapCenterX + (nodeArr[i].x - mapCenterX) * mapScale;
                nodeArr[i].y = mapCenterY + (nodeArr[i].y - mapCenterY) * mapScale;
            }
        }

        function listen() {

            $('#canvas').mousemove(function(e) {

                var movePoint = getMouseMovePoint(e.offsetX, e.offsetY);
                if(movePoint != null) {
                    if(originNodeDrawing) {
                        movePoint.state = NODE_STATE_ORIGIN;
                    } else if(movePoint.state != NODE_STATE_SELECTED) {
                        movePoint.state = NODE_STATE_FOCUSED;
                    }
                }

                if(pathCurDraw.drawing) {// path curr drawing
                    pathCurDraw.to.x = e.offsetX;
                    pathCurDraw.to.y = e.offsetY;
                }

                updateMouseMovePoint(e.offsetX, e.offsetY);
            });

            $("#canvas").mousedown(function(e){

                var downPoint = getMouseDownPoint(e.offsetX, e.offsetY);
                if(downPoint != null) {
                    if(originNodeDrawing) {
                        drawOriginNodeFinish(downPoint);
                    } else {
                        if(!pathCurDraw.drawing) {
                            drawPathCurStart(downPoint);
                        } else {
                            drawPathCurFinish(downPoint);
                        }
                    }
                }
            });

            $("#save_btn").click(function() {

                $("#cover").css("display", "block");
                $("#note_container").css("display", "block");
                $("#note_text").css("display", "block");
                $("#note_text").text('正在生成漫游链接...');
                $("#note_confirm_btn").css("display", "none");

                setTimeout(function () {
                    savePath();
                }, 2000);
            });

            $("#auto_btn").click(function() {

                $("#cover").css("display", "block");
                $("#note_container").css("display", "block");
                $("#note_text").css("display", "block");
                $("#note_text").text('正在自动规划路径...');
                $("#note_confirm_btn").css("display", "none");

                setTimeout(function () {
                    autoPath();
                }, 2000);
            });

            $("#note_confirm_btn").click(function() {
                location.reload(true);
            });

            $("#set_origin_btn").click(function() {
                drawOriginNodeStart();
            });

            $("#reset_btn").click(function() {
                resetUp();
            });

            $(document).keyup(function(e){
                var key =  e.which;
                if(key == 27){
                    drawPathCurCancel();
                    drawOriginNodeCancel();
                }
            });
        }


        function savePath() {

            if(pathNum == 0) {
                alert('至少1条路径！');
                return;
            }

            for(var i = 0; i < nodeNum; i++) {
                var id = pathObj[i].id;
                pathObj[i][2].length = 0;
                for(var j = 0; j < pathNum; j++) {
                    if(id == pathArr[j].fromPoint.id) {
                        if($.inArray(pathArr[j].toPoint.id, pathObj[i][2]) == -1) {
                            pathObj[i][2].push(pathArr[j].toPoint.id);
                        }
                    } else if(id == pathArr[j].toPoint.id) {
                        if($.inArray(pathArr[j].fromPoint.id, pathObj[i][2]) == -1) {
                            pathObj[i][2].push(pathArr[j].fromPoint.id);
                        }
                    }
                }
            }

            dataObj[6][0] = originNodeId;
            dataObj[6][1] = pathObj;
            var data = dataObj[6];
            // console.log('savePath()<<<--- data = ' + JSON.stringify(data));
            // console.log('savePath()<<<--- pathObj = ' + JSON.stringify(pathObj));
            $.post('/item/savePath', {
                data : JSON.stringify(data),
                projectId : projectId
            }, function(result) {

                if(!result) {
                    alert('漫游链接生成失败！');
                    return;
                }
                console.log('savePath()<<<--- result = ' + result);

                var resultObj = null;
                var retCode = null;
                try {
                    resultObj = JSON.parse(result);
                    retCode = resultObj.retCode;
                } catch (e) {
                    alert('漫游链接生成失败！！' + e.name + ": " + e.message);
                    return;
                }
                if(retCode == 0) {
                    var errCode = resultObj.result.errCode;
                    var errCont = resultObj.result.errCont;
                    alert('漫游链接生成失败！原因：' + errCont);
                    switch(errCode) {
                        case -1:
                            alert('账号或密码错误！');
                            console.log('submit()<<<---retCode != 1');
                            break;
                        case -2:
                            alert('账号不存在！');
                            console.log('submit()<<<---retCode != 1');
                            break;
                    }
                } else if(retCode == 1) {
                    var linkAddress = 'http://www.maptopro.com/browser/browser/projectId/' + projectId;
                    $("#note_text").html('漫游链接生成成功！地址：<a href="' + linkAddress + '">' + linkAddress + '</a>');
                    $("#note_confirm_btn").css("display", "none");
                }
                // alert(result);
                // console.log('savePath()<<<--- result = ' + result);
                // window.location = '?r=test/browser&url=' + result;
            },
            'text');
        }

        function autoPath() {

            $.post('/item/autoPath', {
                projectId : projectId
            }, function(result) {

                if(!result) {
                    alert('自动处理失败！');
                    return;
                }

                console.log('autoPath()<<<--- result = ' + result);

                var resultObj = null;
                var retCode = null;
                try {
                    resultObj = JSON.parse(result);
                    retCode = resultObj.retCode;
                } catch (e) {
                    alert('自动处理失败！' + e.name + ": " + e.message);
                    return;
                }
                if(retCode == 0) {
                    var errCode = resultObj.result.errCode;
                    var errCont = resultObj.result.errCont;
                    alert('自动处理失败！原因：' + errCont);
                    switch(errCode) {
                        case -1:
                            alert('账号或密码错误！');
                            console.log('submit()<<<---retCode != 1');
                            break;
                        case -2:
                            alert('账号不存在！');
                            console.log('submit()<<<---retCode != 1');
                            break;
                    }
                } else if(retCode == 1) {
                    $("#note_text").text('自动规划路径成功！如果有不正确的地方，您可以手动修改，然后保存即可。');
                    $("#note_confirm_btn").css("display", "");
                }
            },
            'text');
        }

        function getMouseMovePoint(mouseX, mouseY) {

            for(var i = 0; i < nodeNum; i++) {
                var point = nodeArr[i];
                if((point.x - nodeRadius) <= mouseX && mouseX <= (point.x + nodeRadius) &&
                    (point.y - nodeRadius) <= mouseY && mouseY <= (point.y + nodeRadius)) {
                    return point;
                }
            }
            return null;
        }

        function updateMouseMovePoint(mouseX, mouseY) {

            for(var i = 0; i < nodeNum; i++) {
                var point = nodeArr[i];
                if((point.x - nodeRadius) > mouseX || mouseX > (point.x + nodeRadius) ||
                    (point.y - nodeRadius) > mouseY || mouseY > (point.y + nodeRadius)) {
                    if(point.state != NODE_STATE_SELECTED) {
                        point.state = NODE_STATE_NORMAL;
                    }
                }
            }
        }

        function getMouseDownPoint(mouseX, mouseY) {
            // console.log('getMouseDownPoint()<<<--- mouseX = ' + mouseX + ' mouseX = ' + mouseY);

            for(var i = 0; i < nodeNum; i++) {

                var point = nodeArr[i];
                // console.log('getMouseDownPoint()<<<--- point.id = ' + point.id);
                if((point.x - nodeRadius) <= mouseX && mouseX <= (point.x + nodeRadius) &&
                    (point.y - nodeRadius) <= mouseY && mouseY <= (point.y + nodeRadius)) {

                    return point;
                }
            }

            return null;
        }

        function resetUp() {

            // reset node origin
            originNodeId = 0;
            originNodeDrawing = false;
            $("#canvas").css("cursor","default");
            $('#set_origin_btn').attr("disabled", false);

            // reset node all
            for(var i = 0; i < nodeNum; i++) {
                if(nodeArr[i].circle != null) {
                    nodeArr[i].state = NODE_STATE_NORMAL;
                }
            }

            // reset path cur
            pathCur.fromPoint = null;
            pathCur.toPoint = null;
            pathCurDraw.from.x = null;
            pathCurDraw.from.y = null;
            pathCurDraw.to.x = null;
            pathCurDraw.to.y = null;
            pathCurDraw.path = null;
            pathCurDraw.drawing = false;
            pathCurDraw.start = false;

            // reset path all
            pathNum = pathArr.length;
            for(var j = 0; j < pathNum; j++) {
                if(pathArr[j].line != null) {
                    pathArr[j].line.remove();
                }
            }
            pathArr.length = 0;
        }

        function drawMap() {

            if(mapRaster) {
                mapRaster.size = new Size(mapWidth, mapHeight);
            }
        }

        function drawMapOrigin() {

            var canvasOrigin = new Path.Circle(new Point(mapOriginX, mapOriginY), canvasOriginRadius);
            canvasOrigin.fillColor = 'black';
        }

        function drawNode() {

            for(var i = 0; i < nodeNum; i++) {
                nodeArr[i].state = NODE_STATE_NORMAL;
                nodeArr[i].circle = new Path.Circle(new Point(nodeArr[i].x, nodeArr[i].y), nodeRadius);
                nodeArr[i].circle.fillColor = 'black';
            }
        }

        function drawNodeColor() {

            for(var i = 0; i < nodeNum; i++) {
                if(nodeArr[i].circle != null) {
                    if(i == originNodeId) {
                        nodeArr[i].circle.fillColor = 'green';
                    } else {
                        switch(nodeArr[i].state) {
                            case NODE_STATE_ORIGIN:
                                nodeArr[i].circle.fillColor = 'green';
                                break;
                            case NODE_STATE_NORMAL:
                                nodeArr[i].circle.fillColor = 'black';
                                break;
                            case NODE_STATE_FOCUSED:
                                nodeArr[i].circle.fillColor = '#00BFFF';
                                break;
                            case NODE_STATE_SELECTED:
                                nodeArr[i].circle.fillColor = '#00BFFF';
                                break;
                        }
                    }
                }
            }
        }

        function drawOriginNodeStart() {

            originNodeDrawing = true;
            $("#canvas").css("cursor","crosshair");
            $('#set_origin_btn').attr("disabled", true);
        }

        function drawOriginNodeFinish(point) {

            originNodeDrawing = false;
            originNodeId = point.id;
            $("#canvas").css("cursor","default");
            $('#set_origin_btn').attr("disabled", false);
        }

        function drawOriginNodeCancel() {

            $("#canvas").css("cursor","default");
            originNodeDrawing = false;
            $('#set_origin_btn').attr("disabled", false);
        }

        function getNodeIndexById(id) {

            nodeNum = nodeArr.length;
            for(var i = 0; i < nodeNum; i++) {
                if(id == nodeArr[i].id) {
                    return i;
                }
            }
            return -1;
        }

        function nodeInPath(id) {

            console.log('nodeInPath()<<<--- id = ' + id);
            pathNum = pathArr.length;
            for(var i = 0; i < pathNum; i++) {
                // console.log('nodeInPath()<<<--- i = ' + i);
                // console.log('nodeInPath()<<<--- pathArr[i].fromPoint.id = ' + pathArr[i].fromPoint.id);
                // console.log('nodeInPath()<<<--- pathArr[i].toPoint.id = ' + pathArr[i].toPoint.id);
                if(id == pathArr[i].fromPoint.id || id == pathArr[i].toPoint.id) {
                    console.log('nodeInPath()<<<--- true');
                    return true;
                }
            }
            return false;
        }

        function drawPath() {

            for(var i = 0; i < nodeNum; i++) {
                var pathNum = pathObj[i][2].length;
                if(pathNum > 0) {// path
                    var fromPoint = nodeArr[i];
                    for(var j = 0; j < pathNum; j++) {
                        pathObj[i][2][j] = Math.floor(pathObj[i][2][j]);
                        var toPoint = nodeArr[pathObj[i][2][j]];
                        var path = {};
                        path.fromPoint = fromPoint;
                        path.toPoint = toPoint;
                        var line = new Path.Line(path.fromPoint, path.toPoint);
                        line.strokeWidth = 2;
                        path.line = line;
                        path.state = PATH_STATE_NORMAL;
                        addPath(path);
                    }
                }
            }
        }

        function drawPathColor() {

            pathNum = pathArr.length;
            for(var i = 0; i < pathNum; i++) {
                if(pathArr[i].line != null) {
                    // pathArr[i].line.strokeColor = '#00BFFF';
                    switch(pathArr[i].state) {
                        case PATH_STATE_NORMAL:
                            pathArr[i].line.strokeColor = '#00BFFF';
                            break;
                        case PATH_STATE_FOCUSED:
                            pathArr[i].line.strokeColor = 'green';
                            break;
                        case NODE_STATE_SELECTED:
                            pathArr[i].line.strokeColor = 'green';
                            break;
                    }
                }
            }

        }

        function addPath(path) {

            for(var i = 0; i < pathNum; i++) {
                if((path.fromPoint.id == pathArr[i].fromPoint.id && path.toPoint.id == pathArr[i].toPoint.id) ||
                    (path.fromPoint.id == pathArr[i].toPoint.id && path.toPoint.id == pathArr[i].fromPoint.id)) {
                    console.log('addPath()<<<--- exist the path !');
                    return;
                }
            }

            // path from & to point color
            path.fromPoint.state = NODE_STATE_SELECTED;
            path.toPoint.state = NODE_STATE_SELECTED;
            // console.log('addPath()<<<--- path.fromPoint.id = ' + path.fromPoint.id);
            // console.log('addPath()<<<--- path.toPoint.id = ' + path.toPoint.id);

            path.state = PATH_STATE_NORMAL;
            path.line.onMouseEnter = function(event) {
                console.log('addPath()<<<--- event = ' + event);

                if(pathCurDraw.drawing) {
                    return;
                }

                var point = getMouseMovePoint(event.point.x, event.point.y);
                if(point) {
                    return;
                }

                var index = getPathIndex(this.id);
                if(index >= 0) {
                    pathArr[index].state = PATH_STATE_FOCUSED;
                }

                // this.strokeColor = 'green';
            };
            path.line.onMouseLeave = function(event) {
                var index = getPathIndex(this.id);
                if(index >= 0) {
                    pathArr[index].state = PATH_STATE_NORMAL;
                }
            };
            path.line.onMouseDown = function(event) {
                var point = getMouseMovePoint(event.point.x, event.point.y);
                if(point) {
                    return;
                }
                var index = getPathIndex(this.id);
                if(index >= 0) {
                    pathArr[index].state = PATH_STATE_SELECTED;
                    deletePath(index);
                }
            };
            pathArr.push(path);
            pathNum = pathArr.length;
            console.log('addPath()<<<--- pathNum = ' + pathArr.length);
        }

        function deletePath(index) {

            if(index < 0) {
                return;
            }

            if(pathArr.length < 0) {
                return;
            }

            if(pathCurDraw.drawing) {
                return;
            }

            var fromNodeId = pathArr[index].fromPoint.id;
            var toNodeId = pathArr[index].toPoint.id;

            pathArr[index].line.remove();
            pathArr[index] = null;
            pathArr.splice(index, 1);// splice(index,len,[item]) will change origin array
            pathNum = pathArr.length;

            if(!nodeInPath(fromNodeId)) {
                var fromNodeIndex = getNodeIndexById(fromNodeId);
                if(fromNodeIndex >= 0) {
                    nodeArr[fromNodeIndex].state = NODE_STATE_NORMAL;
                }
            }
            if(!nodeInPath(toNodeId)) {
                var toNodeIndex = getNodeIndexById(toNodeId);
                if(toNodeIndex >= 0) {
                    nodeArr[toNodeIndex].state = NODE_STATE_NORMAL;
                }
            }
        }

        function getPathIndex(id) {

            pathNum = pathArr.length;
            for(var i = 0; i < pathNum; i++) {
                if(id == pathArr[i].line.id) {
                    return i;
                }
            }
            return -1;
        }

        function drawPathCurStart(point) {

            if(!pathCurDraw.drawing) {

                pathCurDraw.start = true;

                pathCur.fromPoint = point;
                pathCur.fromPoint.state = NODE_STATE_SELECTED;

                pathCurDraw.from.x = pathCur.fromPoint.x;
                pathCurDraw.from.y = pathCur.fromPoint.y;
                pathCurDraw.to.x = pathCur.fromPoint.x;
                pathCurDraw.to.y = pathCur.fromPoint.y;

                pathCurDraw.path = new Path.Line(pathCurDraw.from, pathCurDraw.to);
                pathCurDraw.path.strokeColor = '#00BFFF';
                pathCurDraw.path.strokeWidth = 2;
            }
        }

        function drawPathCur() {

            if(pathCurDraw.start) {

                pathCurDraw.drawing = true;

                pathCurDraw.path.segments[1].point.x = pathCurDraw.to.x;
                pathCurDraw.path.segments[1].point.y = pathCurDraw.to.y;
            }
        }

        function drawPathCurFinish(point) {

            if(pathCurDraw.drawing) {

                pathCurDraw.start = false;
                pathCurDraw.drawing = false;

                pathCur.toPoint = point;
                pathCur.toPoint.state = NODE_STATE_SELECTED;

                pathCurDraw.path.remove();

                var path = {};
                path.fromPoint = pathCur.fromPoint;
                path.toPoint = pathCur.toPoint;
                var line = new Path.Line(path.fromPoint, path.toPoint);
                line.strokeWidth = 2;
                path.state = PATH_STATE_NORMAL;
                path.line = line;
                addPath(path);
            }
        }

        function drawPathCurCancel() {

            if(pathCurDraw.drawing) {
                pathCurDraw.start = false;
                pathCurDraw.drawing = false;
                pathCurDraw.path.remove();

                if(!inPathArr(pathCur.fromPoint.id)) {
                    pathCur.fromPoint.state = NODE_STATE_NORMAL;
                }
            }
        }

        function inPathArr(id) {

            for(var i = 0; i < pathNum; i++) {
                if(id == pathArr[i].fromPoint.id || id == pathArr[i].toPoint.id) {
                    return true;
                }
            }
            return false;
        }

        function canvasAnimate() {

            requestAnimationFrame(canvasAnimate);
            canvasRender();
        }

        function canvasRender() {
            drawNodeColor();
            drawPathColor();
            drawPathCur();
        }
    }
}
});